package com.atguigu.config;

import com.atguigu.bean.Car;
import com.atguigu.bean.CarMul;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * bean的生命周期
 *  ben创建--初始化--销毁的过程
 *  ---在初始化之前执行 接口 BeanPostProcessor 中 postProcessBeforeInitialization---
 *  初始化:
 *      调用的时机-对象初始化并赋值好,以后-在调用初始
 *      单实例:程序启动好以后就调用初始化
 *      多实例:程序中获取的时候创建
 *  在初始化执行之后 执行postProcessBeforeInitialization
 *  销毁：
 *      单实例-容器关闭时候销毁
 *      多实例-容器不会管理这个bean;容器不会调用销毁方法
 *
 *  容器管理bean的生命周期 我们可以自定义初始化和销毁方法
 *  1)指定初始化和销毁方法--@Bean(initMethod = "init", destroyMethod = "destory")
 *  2) 通过Bean实现特定的接口
 *      InitializingBean接口中afterPropertiesSet方法执行初始化
 *      DisposableBean接口中destroy方法执行销毁
 *  3)、可以使用JSR250
 *      @PostConstruct 标注方法上进行初始化
 *      @PreDestroy  标注方法进行清理工作
 *  4) BeanPostProcessor【接口】bean后置处理器
 *       postProcessBeforeInitialization：初始化之前
 *       postProcessAfterInitialization：初始化之后
 *
 * BeanPostProcessor的原理
 * 总体结构位置:
 * 		populateBean(beanName, mbd, instanceWrapper); //给bean进行属性赋值
 * 		initializeBean(beanName, exposedObject, mbd);
 * 		{
 * 			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); //所有bean的前置处理
 * 			invokeInitMethods(beanName, wrappedBean, mbd); //调用init方法--可以接口可以是注解
 * 			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); //bean中后置处理起
 * 		}
 */
@ComponentScan(basePackages = "com.atguigu.bean")
@Configuration
public class MainConfigOgLifeCycle {

    @Bean(initMethod = "init", destroyMethod = "destory")
    public Car car() {
        return new Car();
    }

    @Scope(scopeName = "prototype")
    @Bean(initMethod = "init", destroyMethod = "destory")
    public CarMul carMul() {
        return new CarMul();
    }
}
